package rpc.server;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import common.Common;

import java.io.IOException;

/**
 * @author daxue0929
 * @date 2023/2/17
 */

public class ServerRPC {

    private final static String RPC_QUEUE_NAME = "rpc_queue";

    public static void main(String[] args) throws IOException {
        Channel channel = Common.getChannel();

        //生命一个rpc 队列
        channel.queueDeclare(RPC_QUEUE_NAME, true, false, false, null);

        //一次只处理一条消息
        channel.basicQos(1);

        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                /*定义消息属性*/
                AMQP.BasicProperties replyProps = new AMQP.BasicProperties
                    .Builder()
                    .correlationId(properties.getCorrelationId())
                    .build();

                String response = "";
                String message = new String(body, "UTF-8");
                System.out.println("收到的消息:" + message);
                channel.basicAck(envelope.getDeliveryTag(), false);
                int n = Integer.parseInt(message);
                response += fib(n);
                System.out.println("计算结果:" + response);
                /*向回调队列发送结果*/
                channel.basicPublish("", properties.getReplyTo(), replyProps, response.getBytes("UTF-8"));
                synchronized (this) {
                    this.notify();
                }
            }
        };

        /*消费消息*/
        channel.basicConsume(RPC_QUEUE_NAME, false, consumer);
        while (true) {
            synchronized (consumer) {
                try {
                    consumer.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static int fib(int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        return fib(n - 1) + fib(n - 2);
    }
}
